unit ColorMapping;

interface

uses
  System.UITypes, Math;

  function ColorForValue(const Value : Integer) : TAlphaColor;

implementation

// From http://stackoverflow.com/questions/17743821/how-to-convert-hsb-to-rgb
function RGBFP(R, G, B: Double): TAlphaColor;
const
  RGBmax = 255;
begin
  TAlphaColorRec(Result).A := $FF;
  TAlphaColorRec(Result).R := Round(RGBmax * R);
  TAlphaColorRec(Result).G := Round(RGBmax * G);
  TAlphaColorRec(Result).B := Round(RGBmax * B);
end;

// From http://stackoverflow.com/questions/17743821/how-to-convert-hsb-to-rgb
function HSVtoRGB(H, S, V: Double): TAlphaColor;
var
  i: Integer;
  f, p, q, t: Double;
begin
  Assert(InRange(H, 0.0, 1.0));
  Assert(InRange(S, 0.0, 1.0));
  Assert(InRange(V, 0.0, 1.0));

  if S = 0.0 then
  begin
    // achromatic (grey)
    Result := RGBFP(V, V, V);
    exit;
  end;

  H := H * 6.0; // sector 0 to 5
  i := floor(H);
  f := H - i; // fractional part of H
  p := V * (1.0 - S);
  q := V * (1.0 - S * f);
  t := V * (1.0 - S * (1.0 - f));
  case i of
  0:
    Result := RGBFP(V, t, p);
  1:
    Result := RGBFP(q, V, p);
  2:
    Result := RGBFP(p, V, t);
  3:
    Result := RGBFP(p, q, V);
  4:
    Result := RGBFP(t, p, V);
  else
    Result := RGBFP(V, p, q);
  end;
end;

function ColorForValue(const Value : Integer) : TAlphaColor;
const
  MaxValue = 200;
begin
  // Simple hue-only, using Value in range 0-MaxValue, wrapping.
  // Hue must be in range 0-1, so wrap to MaxValue and then shrink 0-1.
  Result := HSVtoRGB((Value mod MaxValue) / MaxValue, 1.0, 1.0);
end;

end.
